/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import javax.swing.SwingUtilities;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JOptionPane;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.Point;
import javax.swing.Action;
import javax.swing.AbstractAction;
import java.util.ArrayList;
import java.awt.GridLayout;
import java.awt.GridBagConstraints;
import javax.swing.JTextPane;

class  ReversiUI implements ActionListener, MouseListener
                                     {
     //Creation of menu items
     protected JMenuItem i1,i2,i3,b1,b2,b3,b4,b5,b6;
     protected Action eightByEight,sixBySix,custom,leastPieces,mostPieces,eightByEight3D;
     protected Action act_PvAI, act_AIvAI, act_PvP;
     protected ArrayList<Point> p = new ArrayList<Point>();
       
     MyPanel myPanel;
     Melchior3 ai;
     Melchior3ThreeD ai3D;
     My3DPanel my3DPanel;
     Manager mngr;
     Manager3D mngr3D;
     JPanel content;
     JFrame f;
     static ReversiUI ui;
     boolean inBounds,winWithMostPieces,is3DGame,PvAI,AIvAI,doRestOfFunction;
    
     int[] lastMove = new int[2];
     
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
    
    public ReversiUI()//Initialization of things we need to run the game
    {
        is3DGame = false;
        inBounds = true;
        AIvAI = false;
        winWithMostPieces = true;
        PvAI = false;
        f = new JFrame("Reversi");

        content = new JPanel(new GridLayout(3,4,25,25));
        mngr3D = new Manager3D(8);
        my3DPanel = new My3DPanel(this);
        
        
        myPanel = new MyPanel(this);
        myPanel.addMouseListener(this);
        mngr = new Manager(myPanel.board_size);
        
        ai = new Melchior3(myPanel.board_size,-1);
    }
    
    public void setBoardSize(int size)//If not a 3D game, sets 2D board, 
    {                                //else we set the 3D board size
        if(!is3DGame){
            myPanel.setBoardSize(size);
            myPanel.repaint();
        }
        else{
            my3DPanel.setBoardSize(size);
            my3DPanel.repaint();
            
        }
    }
    
    public void createMenuBar()//Initialzing the menu bar
    {
        eightByEight = new _8x8("8x8",null,"Change to 8x8 board", new Integer(KeyEvent.VK_8),ui);
        sixBySix = new _6x6("6x6",null,"Change to 6x6 board", new Integer(KeyEvent.VK_6),ui);
        custom = new customSize("Custom Board size",null,"Change to custom board size", new Integer(KeyEvent.VK_C),ui);
        
        eightByEight3D = new _8x8_3D("8x8x8",null,"Change to 8x8x8 board", new Integer(KeyEvent.SHIFT_MASK+KeyEvent.VK_8),ui);
        
        leastPieces = new LeastPieces("Play for least pieces", null, "Play for least pieces", new Integer(KeyEvent.VK_L),ui);
        mostPieces = new MostPieces("Play for most pieces", null, "Play for most pieces", new Integer(KeyEvent.VK_M),ui);
        
        act_PvAI = new P_v_AI("Start Player vs AI", null, "Start Player vs AI", new Integer(KeyEvent.VK_A),ui);
        act_AIvAI = new AI_v_AI("Start AI vs AI", null, "Start AI vs AI", new Integer(KeyEvent.VK_I),ui);
        act_PvP = new P_v_P("Start Player vs Player", null, "Start Player vs Player", new Integer(KeyEvent.VK_P),ui);
        
        i1 = new JMenuItem(act_PvP);
        i2 = new JMenuItem(act_PvAI);
        i3 = new JMenuItem(act_AIvAI);
        
        i1.addActionListener(this);
        i2.addActionListener(this);
        i3.addActionListener(this);
        
        
        b1 = new JMenuItem(sixBySix);
        b2 = new JMenuItem(eightByEight);
        b3 = new JMenuItem(custom);
        b6 = new JMenuItem(eightByEight3D);
        b4 = new JMenuItem(leastPieces);
        b5 = new JMenuItem(mostPieces);
        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
        b4.addActionListener(this);
        b5.addActionListener(this);
        b6.addActionListener(this);
      }
    
    
    
    public void actionPerformed(ActionEvent e){}
    
    private static void createAndShowGUI() {
        System.out.println("Created GUI on EDT? "+
                SwingUtilities.isEventDispatchThread());
        
        ui = new ReversiUI();
        ui.createMenuBar();
                  
        JMenuBar b = new JMenuBar();
              
        JMenu game = new JMenu("Game");
        JMenu board = new JMenu("Change Board Size");
        
        game.add(ui.i1);
        game.add(ui.i2);
        //game.add(ui.i3);
        game.add(ui.b4);
        game.add(ui.b5);

        board.add(ui.b1);
        board.add(ui.b2);
        board.add(ui.b3);
        board.add(ui.b6);
        
        b.add(game);
        b.add(board);
        ui.f.setJMenuBar(b);
        
        ui.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ui.f.add(ui.myPanel);
        
        ui.f.pack();
        ui.f.setVisible(true);
    }
       
    public void mousePressed(MouseEvent e) {}
    
    public void mouseReleased(MouseEvent e) {}
    
    public void mouseEntered(MouseEvent e) {}
    
    public void mouseExited(MouseEvent e) {}
    
    public void mouseClicked(MouseEvent e) {
        System.out.println("CLICKED");
        int[] moves = new int[2];
        
        Point po = calcPoint(e.getPoint(),(100+(550/myPanel.board_size)));
                
        int x_point = (int)po.getX();
        int y_point = (int)po.getY();
        
        lastMove[0] = x_point;
        lastMove[1] = y_point;
        doRestOfFunction = false;
        
        if(e.getX()<650 && e.getX()>100 && e.getY()<650 && e.getY()>100){
                                                //Enter if we are in the boundaries of the board
        	doRestOfFunction = false;
            
           if( !mngr.board.noMoreValidMoves(1)) //Enter if black has valid moves 
        	{
        	   doRestOfFunction = mngr.insertPiece(x_point, y_point);
        	  
        	   if(!doRestOfFunction) //If insertPiece returns false we display an error message
        		 JOptionPane.showMessageDialog(null, "Invalid Move!", "Error", JOptionPane.ERROR_MESSAGE);
        	}
           else
               doRestOfFunction = true;
         
                myPanel.repaint();
        }
        if(mngr.board.noMoreValidMoves(1) || doRestOfFunction){
	        long time = 100000000;
	        
	        if(PvAI){  //Enter if we have Player vs AI enabled
	           
	            ai.makeMove(myPanel.board_size, mngr.board.board, lastMove, new Long(time), moves);
	            if(moves[0]!=-1 && moves[1]!=-1)
	            	mngr.insertPiece(moves[0],moves[1]);
	            myPanel.repaint();
	            
	            while(mngr.board.noMoreValidMoves(1)){ //If black has no moves we continue to allow AI to move
	            	
	                ai.makeMove(myPanel.board_size, mngr.board.board, lastMove, new Long(time), moves);
	            if(moves[0]!=-1 && moves[1]!=-1)
	            	mngr.insertPiece(moves[0],moves[1]);
	            else
	            	break;
                        
                   
	            myPanel.repaint();
	            }
	            }
	                
	        }
        }
        
    public Point calcPoint(Point p, int size){
        int x_point = 2;
        int y_point = 0;     //Here we calculate the X, Y coordinates for each mouse click
        
        if(is3DGame){      
        for(int x=0;x<=myPanel.board_size;x++)
          if(p.getX()>=size*x && p.getX()<size*(x+1))
               x_point = x;
       
        for(int y=0;y<=myPanel.board_size;y++)
           if(p.getY()>=size*y && p.getY()<size*(y+1))
               y_point = y;
        }
        else{
        for(int x=0;x<=myPanel.board_size;x++)
           if(p.getX()>=100+(550/myPanel.board_size)*x && p.getX()<100+(550/myPanel.board_size)*(x+1))
               x_point = x;
       
        for(int y=0;y<=myPanel.board_size;y++)
           if(p.getY()>=100+(550/myPanel.board_size)*y && p.getY()<100+(550/myPanel.board_size)*(y+1))
               y_point = y;
        }
        
        if(x_point==myPanel.board_size)
            x_point--;
        if(y_point==myPanel.board_size)
            y_point--;
        
        return new Point(x_point,y_point);
        
    }
    
    
}

 class My3DPanel extends JPanel{ //Class to display 3D Game
    ReversiUI ui;  
    final int default_size = 8;
    int board_size,x;
    Mini3DPanels panel;
    String blackCount, whiteCount, turn, win = "";
    JTextPane txtPane = new JTextPane();
    GridBagConstraints c = new GridBagConstraints();
           
   public My3DPanel(ReversiUI _ui) {
        setBorder(BorderFactory.createLineBorder(Color.black));
        ui = _ui;
        board_size = default_size;
        createMiniPanels();
        
    }
   
   public void createMiniPanels() //Here we call the creation of each 2D board 
   {                              //for the 3D game
        for(x=0;x<board_size;x++)
        {
            panel = new Mini3DPanels(ui,this);
            panel.setBoardLevel(x);
            ui.content.add(panel);
           // repaint();
        }
        if(x<default_size)  //Fill the remaining spots with empty items if boardsize is less than 8.
            for(int y=default_size-(default_size-x);y<default_size;y++)
                ui.content.add(new JLabel(""));
        
        ui.content.add(new JLabel(""));
        
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 50;      //make this component tall
        c.weightx = 0.0;
        c.gridwidth = 2;
        c.gridx = 1;
        c.gridy = 2;
        //pane.add(button, c);
        ui.content.add(txtPane,c); //Using text pane to update to the user with the current game stats
               
        ui.content.add(new JLabel(""));
        
   }
   
   public void updatePane() //Updates the Text Pane with current game stats
   {
        blackCount = new String("Black Pieces: "  + ui.mngr3D.board.numBlack);
        whiteCount = new String("White Pieces: " + ui.mngr3D.board.numWhite);
        turn = new String("Turn: " + ui.mngr3D.turn);
        
        txtPane.setText("");
        txtPane.replaceSelection(blackCount + "\n" + whiteCount + "\n" + turn + "\n\n");
   }
   
   public void setBoardSize(int size)
    {
        board_size = size;
        ui.mngr3D = new Manager3D(size);
        ui.f.remove(ui.content);
        ui.content = new JPanel(new GridLayout(3,4,25,25));
        createMiniPanels();
        
        ui.f.add(ui.content);
        ui.f.pack();
    }
   
    @Override 
   public Dimension getPreferredSize() {
        return new Dimension(975,975);
    }
    @Override
   public void paintComponent(Graphics g) {
        super.paintComponent(g);  
        g.setColor(Color.ORANGE);
        g.fillOval(100,100,15,15);       

   } 
    
 }
 
 class Mini3DPanels extends JPanel implements MouseListener{ 
    ReversiUI ui;                   //Mini boards that represent the 3D board
    My3DPanel p;
    final int default_size = 8;
    int board_size;
    int board_level;
        
     public Mini3DPanels(ReversiUI _ui, My3DPanel _p) {
        setBorder(BorderFactory.createLineBorder(Color.black));
        ui = _ui;
        p = _p;
        board_size = _p.board_size;
        this.addMouseListener(this);
     }
     
   public void setBoardSize(int size)
    {
        board_size = size;
        ui.mngr3D = new Manager3D(size);
        repaint();
    }     
     
    @Override 
    public Dimension getPreferredSize() {
        return new Dimension(200,200);
    }
    
    public void setBoardLevel(int lvl) 
    {
        board_level = lvl;
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        //painting the board itself
        g.setColor(Color.DARK_GRAY);
        g.fillRect(0, 0, 200, 200);
        
        g.setColor(Color.ORANGE);
        g.setColor(Color.RED);      
        
       for(int x=1;x<board_size;x++)
        {
            g.drawLine(0+(200/board_size)*x, 0, 0+(200/board_size)*x, 200);
            g.drawLine(0,0+(200/board_size)*x,200,0+(200/board_size)*x);
        }
       
        //Display the pieces on the board
       for(int x=0;x<board_size;x++)
        {
           for(int y=0;y<board_size;y++)
           {
                if(ui.mngr3D.board.board[x][y][board_level]==0)
                  continue;
              
                switch(ui.mngr3D.board.board[x][y][board_level]){
                  case -1 : g.setColor(Color.WHITE); break;
                  case  1 : g.setColor(Color.BLACK); break;
                  default : break;
              }
               g.fillOval((200/board_size)*x+3,(200/board_size)*y+3,(200/board_size-5),(200/board_size-5));
              
           }
        }
        
        //Checking if display needs to be shown for a winner
        int winner = 0;
        if((winner = ui.mngr3D.someoneWon()) != 0) 
        {
            if(!ui.winWithMostPieces)
                winner = winner * -1;
                
        	if(winner != 2)
        		ui.my3DPanel.win = new String("Player " + winner + " won!!!!");
                else
        		ui.my3DPanel.win = new String("DRAW!!!!!!!!!!");
            ui.my3DPanel.txtPane.replaceSelection(ui.my3DPanel.win + "\n");
        }
       
    }
    
    public void mousePressed(MouseEvent e) {}
    
    public void mouseReleased(MouseEvent e) {}
    
    public void mouseEntered(MouseEvent e) {}
    
    public void mouseExited(MouseEvent e) {}
    
    int[] lastMove = new int[3];
    public void mouseClicked(MouseEvent e) {
        System.out.println("CLICKED");
        Point po = ui.calcPoint(e.getPoint(),(200/board_size));
        boolean doRestOfFunction;
        int[] moves = new int[3];
                
        int x_point = (int)po.getX();
        int y_point = (int)po.getY();
        
        lastMove[0] = x_point;
        lastMove[1] = y_point;
        lastMove[2] = board_level;
        doRestOfFunction = false;
        
        if(e.getX()<200 && e.getX()>0 && e.getY()<200 && e.getY()>0){
        	
                if(!ui.mngr3D.board.noMoreValidMoves(1)){
                  doRestOfFunction = ui.mngr3D.insertPiece(x_point, y_point, board_level);
                  if(!doRestOfFunction)
                    JOptionPane.showMessageDialog(null, "Invalid Move!", "Error", JOptionPane.ERROR_MESSAGE);
                }
                else
                    doRestOfFunction = true;
                
                ui.content.repaint();              
        }

        
        if(ui.mngr3D.board.noMoreValidMoves(1) || doRestOfFunction){
        if(ui.PvAI){
	            long time = 100000;    
	            ui.ai3D.makeMove(ui.my3DPanel.board_size, ui.mngr3D.board.board, lastMove, new Long(time), moves);
	            if(moves[0]!=-1 && moves[1]!=-1 && moves[2]!=-1)
                        ui.mngr3D.insertPiece(moves[0],moves[1],moves[2]);
	            ui.content.repaint();
	            
	            while(ui.mngr3D.board.noMoreValidMoves(1)){
	            	ui.ai3D.makeMove(ui.my3DPanel.board_size, ui.mngr3D.board.board, lastMove, new Long(time), moves);
	            if(moves[0]!=-1 && moves[1]!=-1 && moves[2]!=-1)
	            	ui.mngr3D.insertPiece(moves[0],moves[1],moves[2]);
	            else
	            	break;
                    ui.content.repaint();
                   
	            }
	            }
            
           }
            
            ui.my3DPanel.updatePane();
              
    }
 
 }
 
 class MyPanel extends JPanel { //Display of the 2D board

    ReversiUI ui;  
    final int default_size = 8;
    int board_size;
    int[][] lpoints;
    
    public MyPanel(ReversiUI _ui) {
        setBorder(BorderFactory.createLineBorder(Color.black));
        ui = _ui;
        board_size = default_size;
    }
     
    public void setBoardSize(int size)
    {
        board_size = size;
        ui.mngr = new Manager(size);
        repaint();
    }
    
        @Override 
    public Dimension getPreferredSize() {
        return new Dimension(750,750);
    }
        @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);       
        
        //Paints the board
        g.setColor(Color.DARK_GRAY);
        g.fillRect(100, 100, 550, 550);
        
        g.setColor(Color.ORANGE);
        
        for(int x=1;x<board_size;x++)
        {
            g.drawLine(100+(550/board_size)*x, 100, 100+(550/board_size)*x, 650);
            g.drawLine(100,100+(550/board_size)*x,650,100+(550/board_size)*x);
        }
        
        //Display user stats
        g.setColor(Color.BLACK);
        
        g.drawString("Turn: Player "+ ui.mngr.turn, 82, 20);
        
        g.drawString("White pieces: " + ui.mngr.board.numWhite, 350, 20);
        g.drawString("Black pieces: " + ui.mngr.board.numBlack, 350, 40);
        
        //Check for winner display
        int winner = 0;
        if((winner = ui.mngr.someoneWon()) != 0) 
        {
            if(!ui.winWithMostPieces)
                winner = winner * -1;
                
        	if(winner != 2)
        		g.drawString("Player " + winner + " won!!!!", 200, 20);
                else
        		g.drawString("DRAW!!!!!!!!!!", 200, 20);
        }

        
        //Paint pieces to board
        for(int x=0;x<board_size;x++)
        {
           for(int y=0;y<board_size;y++)
           {
              if(ui.mngr.board.board[x][y]==0)
                  continue;
              
              switch(ui.mngr.board.board[x][y]){
                  case -1 : g.setColor(Color.WHITE); break;
                  case  1 : g.setColor(Color.BLACK); break;
                  default : break;
              }
              
              g.fillOval(100+(550/board_size)*x+3,100+(550/board_size)*y+3,(550/board_size-5),(550/board_size-5));
            }
        }
        
    }  
}
 
 class P_v_AI extends AbstractAction{//Implementation of the player vs AI button
 
    public P_v_AI(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
        i.PvAI = true;  //We set this to true in the ReversiUI so we know its a PvAI game
        i.ai = new Melchior3(i.myPanel.board_size,-1); //Initialize 2D and 3D game AIs
        i.ai3D = new Melchior3ThreeD(i.my3DPanel.board_size,-1);
        
        if(!i.is3DGame)  //Resets the game to proper boardsize in PvAI mode
            i.setBoardSize(i.myPanel.board_size);
        else{
            i.setBoardSize(i.my3DPanel.board_size);
        }
        
        System.out.println("Gameplay set sucessfully");
    }
}
 
   class P_v_P extends AbstractAction{ //Set gameplay to Player vs Player
 
    public P_v_P(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
        i.PvAI = false; 
        
        if(!i.is3DGame)
            i.setBoardSize(i.myPanel.board_size);
        else{
            i.setBoardSize(i.my3DPanel.board_size);
        }
        
        System.out.println("Gameplay set sucessfully");
    }
}
 
  class AI_v_AI extends AbstractAction{
 
    public AI_v_AI(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
        i.AIvAI = true;
        Melchior3 ai1 = new Melchior3(i.myPanel.board_size,1);
        Melchior3 ai2 = new Melchior3(i.myPanel.board_size,-1);
        
        Melchior3ThreeD ai3D1 = new Melchior3ThreeD(i.my3DPanel.board_size,1);
        Melchior3ThreeD ai3D2 = new Melchior3ThreeD(i.my3DPanel.board_size,-1);
        int winner = -1;
        int[] moves = new int[3];
        int[] lastMove = new int[3];
        
        if(!i.is3DGame){ //if a 2D game run 2D version of AI vs AI
            i.setBoardSize(i.myPanel.board_size);
              
        while((winner = i.mngr.someoneWon()) == 0){
        	long time = 100000;
            System.out.println("AI v AI");
            ai1.makeMove(i.myPanel.board_size, i.mngr.board.board, lastMove, new Long(time), moves);
            if( moves[0] == -1 || moves[1] == -1)
            	break;
            i.mngr.insertPiece(moves[0],moves[1]);
            i.myPanel.repaint();
            
            lastMove[0] = moves[0];
            lastMove[1] = moves[1];
                      
            ai2.makeMove(i.myPanel.board_size, i.mngr.board.board, lastMove, new Long(time), moves);
            if( moves[0] == -1 || moves[1] == -1)
            	break;
            i.mngr.insertPiece(moves[0],moves[1]);    
            i.myPanel.repaint();
            
            lastMove[0] = moves[0];
            lastMove[1] = moves[1];
            
        }
       }
        else{//if a 3D game run 3D version of AI vs AI
          i.setBoardSize(i.my3DPanel.board_size);
          
          while((winner = i.mngr3D.someoneWon()) == 0){
        	  long time = 1000000;
            
            ai3D1.makeMove(i.my3DPanel.board_size, i.mngr3D.board.board, lastMove, new Long(time), moves);
            if(moves[0] == -1 || moves[1] == -1 || moves[2] == -1)
            	break;
            i.mngr3D.insertPiece(moves[0],moves[1],moves[2]);
            i.content.repaint();
            
            lastMove[0] = moves[0];
            lastMove[1] = moves[1];
            lastMove[2] = moves[2];
            
            ai3D2.makeMove(i.my3DPanel.board_size, i.mngr3D.board.board, lastMove, new Long(time), moves);
            if(moves[0] == -1 || moves[1] == -1 || moves[2] == -1)
            	break;
            i.mngr3D.insertPiece(moves[0],moves[1],moves[2]);
            i.content.repaint();
            
            lastMove[0] = moves[0];
            lastMove[1] = moves[1];
            lastMove[2] = moves[2];
        }
      }        
        
    }
  }

class _8x8 extends AbstractAction{ //Set board size to 8x8
 
    public _8x8(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
        if(!i.is3DGame)
            i.setBoardSize(8);
        else{
        i.is3DGame = false;
        i.f.remove(i.content);
        i.f.add(i.myPanel);
        i.f.pack();
        i.setBoardSize(8);
        }
        System.out.println("Board size set sucessfully");
    }
}

class _6x6 extends AbstractAction{
 
    public _6x6(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
        if(!i.is3DGame)
            i.setBoardSize(6);
        else{
        i.is3DGame = false;
        i.f.remove(i.content);
        i.f.add(i.myPanel);
        i.f.pack();
        i.setBoardSize(6);
        }
        System.out.println("Board size set sucessfully");
    }
}

class customSize extends AbstractAction{ //Custom 2D size
 
    public customSize(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
        String num = JOptionPane.showInputDialog("Enter a custom board size (even number)");  
        
        if(!i.is3DGame)
            i.setBoardSize(new Integer(num));
        else{
        i.is3DGame = false;
        i.f.remove(i.content);
        i.f.add(i.myPanel);
        i.f.pack();
        i.setBoardSize(new Integer(num));
        }
        System.out.println("Board size set sucessfully");
    }
}

class _8x8_3D extends AbstractAction{
 
    public _8x8_3D(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
        if(i.is3DGame)
            i.setBoardSize(8);
        else{
        i.is3DGame = true;
        i.f.remove(i.myPanel);
        i.f.add(i.content);
        i.f.pack();
        i.setBoardSize(8);
        }
        System.out.println("Board size set sucessfully");
    }
}

class LeastPieces extends AbstractAction{//Set gameplay to winner has least pieces
 
    public LeastPieces(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
          
          i.winWithMostPieces = false;
          System.out.println("Get the least pieces to win");
    }
}

class MostPieces extends AbstractAction{//Set gameplay to winner has most pieces (default gameplay)
 
    public MostPieces(String text, ImageIcon icon, String desc, Integer mnemonic,ReversiUI _i){
        super(text,icon);
        putValue(SHORT_DESCRIPTION,desc);
        putValue(MNEMONIC_KEY,mnemonic);
        i = _i;
    }
        ReversiUI i;
      public void actionPerformed(ActionEvent e){
          
          i.winWithMostPieces = true;
          System.out.println("Get the most pieces to win");
    }
}

 
